/*
 * Copyright 2024 ziduo.xyz.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package xyz.ziduo.lapcounter;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;

import xyz.ziduo.lapcounter.ui.WaveformView;
import xyz.ziduo.lapcounter.utils.Utils;


public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "LC: " + MainActivity.class.getSimpleName();

    private static final int REQUEST_CODE_START_RUN = 1001;

    // 应用数据根目录
    private static final String FILE_ROOT_DIR = "data";
    // 跑步数据根目录
    // 跑步数据按年份分成子目录放入该目录下，跑步数据文件按日期命名，放入对应年份目录中
    // 2024 > 12-30.txt
    private static final String FILE_RUN_DATA_DIR = "data/rundata";
    // 应用设置文件
    private static final String FILE_SYSTEM_SET = "sys_set.txt";

    private TextView tv_run, tv_my_running_performance,
            tv_worst, tv_best, tv_most_recent, tv_date_most_recent,
            tv_calorie_expenditure,
            tv_mileage_today, tv_mileage_best, tv_mileage_worst, tv_mileage_all,
            tv_pace_today, tv_pace_best, tv_pace_worst, tv_pace_all;
    private WaveformView waveform_1, waveform_2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        readAppSet();
    }

    private void initView() {
        tv_run = findViewById(R.id.tv_run);
        tv_my_running_performance = findViewById(R.id.tv_my_running_performance);
        tv_worst = findViewById(R.id.tv_worst);
        tv_best = findViewById(R.id.tv_best);
        tv_most_recent = findViewById(R.id.tv_most_recent);
        tv_date_most_recent = findViewById(R.id.tv_date_most_recent);
        tv_calorie_expenditure = findViewById(R.id.tv_calorie_expenditure);
        tv_mileage_today = findViewById(R.id.tv_mileage_today);
        tv_mileage_best = findViewById(R.id.tv_mileage_best);
        tv_mileage_worst = findViewById(R.id.tv_mileage_worst);
        tv_mileage_all = findViewById(R.id.tv_mileage_all);
        tv_pace_today = findViewById(R.id.tv_pace_today);
        tv_pace_best = findViewById(R.id.tv_pace_best);
        tv_pace_worst = findViewById(R.id.tv_pace_worst);
        tv_pace_all = findViewById(R.id.tv_pace_all);
        waveform_1 = findViewById(R.id.waveform_1);
        waveform_2 = findViewById(R.id.waveform_2);

        tv_run.setOnClickListener(this);
        tv_my_running_performance.setOnClickListener(this);
        tv_my_running_performance.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                Intent intent = new Intent(MainActivity.this, TestActivity.class);
                startActivity(intent);
                return true;
            }
        });
        tv_worst.setOnClickListener(this);
        tv_best.setOnClickListener(this);
        tv_most_recent.setOnClickListener(this);

        // 为了页面加载好后再执行，以便获得两个波线图的宽高
        this.getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                readRunData(); // 因为readRunData涉及UI更新，所以放在这里
                Resources resources = MainActivity.this.getResources();
                int worstColor = resources.getColor(R.color.worst_waveform_color);
                int bestColor = resources.getColor(R.color.best_waveform_color);
                int mostRecentColor = resources.getColor(R.color.most_recent_waveform_color);
                int allColor = resources.getColor(R.color.all_waveform_color);
                waveform_1.init(WaveformView.ModeType.Mode_3_Waveform, waveform_1.getWidth(), waveform_1.getHeight(),
                        allColor, worstColor, bestColor, mostRecentColor);
                waveform_2.init(WaveformView.ModeType.Mode_1_Waveform, waveform_2.getWidth(), waveform_2.getHeight(),
                        allColor, worstColor, bestColor, mostRecentColor);
            }
        });
    }

    @Override
    public void onClick(View view) {
        if(isFastClick()) return; // 如果是快速点击则不进行响应
        if(view.getId() == R.id.tv_run) { // 跑步
            dplRunView();
        } else if(view.getId() == R.id.tv_my_running_performance) { // 我的成绩
            dplPerformanceView();
        } else if(view.getId() == R.id.tv_worst) { // 最差波线图
            if(tv_worst.getAlpha() < 1.0f) {
                tv_worst.setAlpha(1.0f);
                worstWaveformDplFlag = 1;
            } else {
                tv_worst.setAlpha(0.4f);
                worstWaveformDplFlag = 0;
            }
            waveform3Flag = worstWaveformDplFlag + bestWaveformDplFlag + mostRecentWaveformDplFlag;
            updateMode3Waveform();
        } else if(view.getId() == R.id.tv_best) { // 最好波线图
            if(tv_best.getAlpha() < 1.0f) {
                tv_best.setAlpha(1.0f);
                bestWaveformDplFlag = 2;
            } else {
                tv_best.setAlpha(0.4f);
                bestWaveformDplFlag = 0;
            }
            waveform3Flag = worstWaveformDplFlag + bestWaveformDplFlag + mostRecentWaveformDplFlag;
            updateMode3Waveform();
        } else if(view.getId() == R.id.tv_most_recent) { // 最近波线图
            if(tv_most_recent.getAlpha() < 1.0f) {
                tv_most_recent.setAlpha(1.0f);
                mostRecentWaveformDplFlag = 4;
            }
            else {
                tv_most_recent.setAlpha(0.4f);
                mostRecentWaveformDplFlag = 0;
            }
            waveform3Flag = worstWaveformDplFlag + bestWaveformDplFlag + mostRecentWaveformDplFlag;
            updateMode3Waveform();
        }
    }

    // 显示跑步对话框
    private void dplRunView() {
        View dpl = getLayoutInflater().inflate(R.layout.view_run, null);
        EditText et_lap_length = dpl.findViewById(R.id.et_lap_length);
        RadioButton rb_whole = dpl.findViewById(R.id.rb_whole);
        RadioButton rb_round = dpl.findViewById(R.id.rb_round);
        CheckBox cb_lap_plan = dpl.findViewById(R.id.cb_lap_plan);
        EditText et_lap_plan_num = dpl.findViewById(R.id.et_lap_plan_num);
        EditText et_weight_now = dpl.findViewById(R.id.et_weight_now);
        TextView tv_cancel = dpl.findViewById(R.id.tv_cancel);
        TextView tv_start = dpl.findViewById(R.id.tv_start);

        // 设置成当前的值
        et_lap_length.setHint(String.valueOf(sysSetLapLength));
        if(sysSetIsRoundMode) rb_round.setChecked(true);
        else rb_whole.setChecked(true);
        if(sysSetLapPlanIsCheck) cb_lap_plan.setChecked(true);
        else cb_lap_plan.setChecked(false);
        et_lap_plan_num.setHint(String.valueOf(sysSetLapPlanNum));
        et_weight_now.setHint(String.valueOf(sysSetWeightNow));

        AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
                .setCancelable(true)
                .setView(dpl)
                .create();
        dialog.show();
        Window window = dialog.getWindow();
        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        window.setGravity(Gravity.TOP);
        WindowManager.LayoutParams params = window.getAttributes();
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.width = dpToPx(300);
        params.y = dpToPx(40);
        window.setAttributes(params);

        tv_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dialog.dismiss();
            }
        });

        tv_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 读取当前设置
                int lapLen = 0, planNum = 0, weightNow = 0;
                boolean modeRound = false, planCheck = false;

                String lapLenIn = et_lap_length.getText().toString();
                if(lapLenIn.length() > 0) lapLen = Integer.parseInt(lapLenIn);
                else lapLen = sysSetLapLength;

                if(rb_round.isChecked()) modeRound = true;
                if(cb_lap_plan.isChecked()) planCheck = true;

                String planNumIn = et_lap_plan_num.getText().toString();
                if(planNumIn.length() > 0) planNum = Integer.parseInt(planNumIn);
                else planNum = sysSetLapPlanNum;

                String weightNowIn = et_weight_now.getText().toString();
                if(weightNowIn.length() > 0) weightNow = Integer.parseInt(weightNowIn);
                else weightNow = sysSetWeightNow;

                // 检查设置是否与原来一样，如果不一样就保存设置
                if(lapLen != sysSetLapLength || planNum != sysSetLapPlanNum || weightNow != sysSetWeightNow ||
                        modeRound != sysSetIsRoundMode || planCheck != sysSetLapPlanIsCheck) {
                    sysSetLapLength = lapLen;
                    sysSetLapPlanNum = planNum;
                    sysSetWeightNow = weightNow;
                    sysSetIsRoundMode = modeRound;
                    sysSetLapPlanIsCheck = planCheck;
                    saveAppSet();
                }

                // 开始跑步页面
                // 需要传递：lapLength圈长、isRoundMode是否是回来模式、isLapPlanCheck是否计划圈数、lapPlanNum计划圈数
                if(sysSetLapLength == 0) {
                    Utils.dplAlert(MainActivity.this, "必须设置圈长才能跑步!");
                    return;
                }

                dialog.dismiss();
                Intent intent = new Intent(MainActivity.this, RunningActivity.class);
                intent.putExtra("lapLength", sysSetLapLength);
                intent.putExtra("isRoundMode", sysSetIsRoundMode);
                intent.putExtra("isLapPlanCheck", sysSetLapPlanIsCheck);
                intent.putExtra("lapPlanNum", sysSetLapPlanNum);
                startActivityForResult(intent, REQUEST_CODE_START_RUN);
            }
        });
    }

    // 显示我的成绩对话框
    private void dplPerformanceView() {
        View dpl = getLayoutInflater().inflate(R.layout.view_performance, null);
        TextView tv_export = dpl.findViewById(R.id.tv_export);
        TextView tv_import = dpl.findViewById(R.id.tv_import);
        TextView tv_delete = dpl.findViewById(R.id.tv_delete);
        tv_export.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });
        tv_import.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });
        tv_delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });
        AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
                .setCancelable(true)
                .setView(dpl)
                .create();
        dialog.show();
        Window window = dialog.getWindow();
        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        window.setGravity(Gravity.TOP);
        WindowManager.LayoutParams params = window.getAttributes();
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.width = dpToPx(100);
        params.x = dpToPx(30);
        params.y = dpToPx(100);
        window.setAttributes(params);
    }

    // 应用记录的跑步相关数据
    private double todayCalorieExpenditure = 0; // 今天的热量消耗
    private int todayMileage = 0; // 今天的跑步里程，单位米
    private double todayPace = 0; // 今天的平均配速，单位秒
    private long todayRunsTime = 0; // 今天跑步的总时间，单位毫秒

    private int allMileage = 0; // 跑步的总里程，单位米
    private double allPace = 0; // 跑步的总的平均配速，单位秒
    private int allRunsTime = 0; // 跑步的总时间，单位毫秒

    // 总数据，注意：其内部跑步数据列表每一项为每一次跑步的平均配速
    // mileage为总里程， time为总时间，单位毫秒，paceList的项为该次跑步的平均配速
    private RunData mAllRunData = new RunData();

    private long dateRecentRun = 0; // 代表最后一次跑步的日期，millis
    private int mostRecentInext = 0; // 最近成绩的索引
    private String mostRecentYear = ""; // 最近一次跑步的年份
    private String mostRecentDate = ""; // 最近一次跑步的月日
    private int bestMileage = 0; // 产生最好成绩时的那次跑步的里程，单位米
    private double bestPace = Double.MAX_VALUE; // 产生最好成绩时的那次跑步的平均配速，单位秒
    private String bestYear = ""; // 产生最好成绩时的年份
    private String bestDate = ""; // 产生最好成绩时的月日
    private int bestInext = 0; // 最好成绩的索引
    private int worstMileage = 0; // 产生最差成绩时的那次跑步的里程，单位米
    private double worstPace = 0; // 产生最差成绩时的那次跑步的平均配速，单位秒
    private String worstYear = ""; // 产生最差成绩时的年份
    private String worstDate = ""; // 产生最差成绩时的月日
    private int worstInext = 0; // 最差成绩的索引


    private int worstWaveformDplFlag = 0; // 0位控制最差成绩波形图是否显示
    private int bestWaveformDplFlag = 0 ; // 1位控制最好成绩波形图是否显示
    private int mostRecentWaveformDplFlag = 4; // 2位控制最近成绩波形图是否显示
    private int waveform3Flag = 4; // 默认只显示最近成绩
    // 添加跑步数据，并更新UI
    private void addRunData(RunData runData) {
        readRunData(); // 笨方法

        // 暂时先使用笨方法
        if(true) return;
        // 添加数据
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy MM-dd");
        String[] arr = format.format(date).split(" ");
        String yearStr = arr[0];
        String dateStr = arr[1];
        HashMap<String, ArrayList<MainActivity.RunData>> dateMap = mAllRunDataMap.get(yearStr);
        if(dateMap == null) {
            dateMap = new HashMap<>();
            mAllRunDataMap.put(yearStr, dateMap);
        }
        ArrayList<MainActivity.RunData> runList = dateMap.get(dateStr);
        if(runList == null) {
            runList = new ArrayList<>();
            dateMap.put(dateStr, runList);
        }
        runList.add(runData);

        // 更新相关数据
        int mileage = runData.mileage; // 总长
        long time = runData.time; // 总时长

        // 今天的数据
        todayMileage += mileage;
        todayRunsTime += time;
        todayPace = Utils.countPace(todayRunsTime, todayMileage);
        todayCalorieExpenditure = Utils.countCalorie(sysSetWeightNow, todayMileage);

        // 全部的数据
        allMileage += mileage;
        allRunsTime += time;
        allPace = Utils.countPace(allMileage, allRunsTime);
        mAllRunData.mileage = allMileage;
        mAllRunData.time = allRunsTime;
        double pace_avr = Utils.countPace(time, mileage);
        mAllRunData.paceList.add(pace_avr);

        // 最近 最好 最坏 的数据
        dateRecentRun = date.getTime();
        mostRecentInext = runList.size() - 1;
        mostRecentYear = yearStr;
        mostRecentDate = dateStr;
        if(bestPace > pace_avr) {
            bestPace = pace_avr;
            bestMileage = mileage;
            bestYear = yearStr;
            bestDate = dateStr;
            bestInext = runList.size() - 1;
        }
        if(worstPace < pace_avr) {
            worstPace = pace_avr;
            worstMileage = mileage;
            worstYear = yearStr;
            worstDate = dateStr;
            worstInext = runList.size() - 1;
        }

        // 更新 UI
        tv_date_most_recent.setText(mostRecentYear + "-" + mostRecentDate);
        updateMode3Waveform();
        waveform_2.updateUIMode_1_Waveform(mAllRunData);
        tv_calorie_expenditure.setText(String.format("%.2d", todayCalorieExpenditure));
        tv_mileage_today.setText(String.valueOf(todayMileage));
        tv_mileage_best.setText(String.valueOf(bestMileage));
        tv_mileage_worst.setText(String.valueOf(worstMileage));
        tv_mileage_all.setText(String.valueOf(allMileage));
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // 检查请求码和结果码是否匹配
        if (requestCode == REQUEST_CODE_START_RUN) {
            if(resultCode == RESULT_OK) {
                String result = data.getStringExtra("resultKey");
                // 处理返回的数据，例如更新UI
                // textView.setText(result);
            } else {

            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        readRunData();
    }
// 跑步数据块格式：
    //      块首行：length time，length跑步总长，单位米，time跑步总时长，单位毫秒
    //      数据行：行首一个空格，然后跟本圈配速，单位秒
    // 配速即跑一公里所用时间

    // 保存单次跑步数据的类型
    public class RunData {
        public int mileage; // 总里程，米
        public long time; // 总时长，毫秒
        // 使用double类型记录配速数据，可在波形图显示时更加精准
        public ArrayList<Double> paceList = new ArrayList<>(); // 保存每圈配速，其大小为圈数

        @NonNull
        @Override
        public String toString() {
            StringBuilder runSb = new StringBuilder();
            // 填充首行
            runSb.append(mileage).append(" ").append(time).append("\n");
            // 填充数据行
            for(double pace : paceList) {
                runSb.append(" ").append(pace).append("\n");
            }
            return runSb.toString();
        }
    }
    // 读取跑步数据
    // 跑步数据保存在HashMap中，保存格式为：HashMap<String, HashMap<String, ArrayList<ArrayList<Integer>>>>
    // 年份-月日-跑步次数-跑步数据
    private HashMap<String, HashMap<String, ArrayList<RunData>>> mAllRunDataMap = new HashMap<>();
    @SuppressLint("SetTextI18n")
    private void readRunData() {
        // 先将原有数据清除
        todayCalorieExpenditure = 0; // 今天消耗热量
        todayMileage = 0; // 今天总里程，米
        todayPace = 0; // 今天平均配速，秒
        todayRunsTime = 0; // 今天跑步时长，毫秒
        allMileage = 0; // 总里程，米
        allPace = 0; // 总平均配速，秒
        allRunsTime = 0; // 总时长，毫秒
        mAllRunData = new RunData(); // 总跑步数据，记录每天次的平均配速
        mAllRunDataMap = new HashMap<>(); // 总跑步数据，记录每次的实际相关数据
        dateRecentRun = 0; // 最后一次跑步日期
        mostRecentInext = 0; // 最后一次跑步的索引
        bestMileage = 0; // 最好成绩时的里程
        bestPace = Double.MAX_VALUE; // 最好成绩时的平均配速
        bestYear = ""; // 最好成绩时的年份
        bestDate = ""; // 最好成绩时的月日
        bestInext = 0; // 最好成绩时的索引
        worstMileage = 0; // 最差成绩时的里程
        worstPace = 0; // 最差成绩时的平均配速
        worstYear = ""; // 最差成绩时的年份
        worstDate = ""; // 最差成绩时的月日
        worstInext = 0; // 最差成绩时的索引

        File dataDir = new File(getFilesDir().getAbsolutePath() + "/" + FILE_RUN_DATA_DIR);
        if(!dataDir.exists()) { // 如果不存在跑步数据根目录就创建目录后返回
            if(!dataDir.mkdirs()) {
                Utils.dplAlert(this, "无法创建数据目录");
            }
            return;
        }

        for(File yearDir : dataDir.listFiles()) { // 遍历跑步数据根目录
            if(yearDir.isDirectory()) {
                String yearDirName = yearDir.getName();
                // 月份数据
                HashMap<String, ArrayList<RunData>> dateMap = new HashMap<>();
                mAllRunDataMap.put(yearDirName, dateMap);
                for(File dataFile : yearDir.listFiles()) { // 遍历年份数据根目录
                    if(dataFile.isFile()) {
                        String[] nameArr = dataFile.getName().split("\\.");
                        String dateFileName = nameArr[0];
                        ArrayList<String> linesList = Utils.readFile(MainActivity.this,
                                FILE_RUN_DATA_DIR + "/" + dataFile.getParentFile().getName(), dataFile.getName());
                        // 日数据
                        ArrayList<RunData> runList = new ArrayList<>();
                        dateMap.put(dateFileName, runList);
                        RunData runData = null; // 如果有数据才会创建对象
                        for(String line : linesList) {
                            if(!line.startsWith(" ")) { // 首行
                                if(runData != null) { // 先计算已读取的数据
                                    // 更新应用记录数据
                                    allMileage += runData.mileage; // 总米数
                                    allRunsTime += runData.time; // 总时间
                                    allPace = Utils.countPace(allMileage, allRunsTime); // 总平均配速
                                    double pace_avr = Utils.countPace(runData.time, runData.mileage); // 本次平均配速
                                    mAllRunData.mileage = allMileage;
                                    mAllRunData.time = allRunsTime;
                                    mAllRunData.paceList.add(pace_avr);
                                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM-dd");
                                    Date d = null;
                                    try {
                                        d = sdf.parse(yearDirName + dateFileName);
                                    } catch (ParseException pe) {
                                        Log.e(TAG, "parse date err", pe);
                                    }
                                    if(dateRecentRun < d.getTime()) {
                                        dateRecentRun = d.getTime();
                                        mostRecentInext = runList.size() - 1;
                                        mostRecentYear = yearDirName;
                                        mostRecentDate = dateFileName;
                                    }
                                    if(bestPace > pace_avr) {
                                        bestPace = pace_avr;
                                        bestMileage = runData.mileage;
                                        bestYear = yearDirName;
                                        bestDate = dateFileName;
                                        bestInext = runList.size() - 1;
                                    }
                                    if(worstPace < pace_avr) {
                                        worstPace = pace_avr;
                                        worstMileage = runData.mileage;
                                        worstYear = yearDirName;
                                        worstDate = dateFileName;
                                        worstInext = runList.size() - 1;
                                    }
                                    allPace = Utils.countPace(allRunsTime, allMileage);
                                }
                                // 创建新对象并加入容器
                                runData = new RunData();
                                String[] arr = line.split(" ");
                                runData.mileage = Integer.parseInt(arr[0]);
                                runData.time = Integer.parseInt(arr[1]);
                                runList.add(runData);
                            } else { // 数据行
                                runData.paceList.add(Double.parseDouble(line));
                            }
                        }
                        // 最后还有一个对象
                        allMileage += runData.mileage; // 总米数
                        allRunsTime += runData.time; // 总时间
                        allPace = Utils.countPace(allMileage, allRunsTime); // 总平均配速
                        double pace_avr = Utils.countPace(runData.time, runData.mileage); // 本次平均配速
                        mAllRunData.mileage = allMileage;
                        mAllRunData.time = allRunsTime;
                        mAllRunData.paceList.add(pace_avr);
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM-dd");
                        Date d = null;
                        try {
                            d = sdf.parse(yearDirName + dateFileName);
                        } catch (ParseException pe) {
                            Log.e(TAG, "parse date err", pe);
                        }
                        if(dateRecentRun < d.getTime()) {
                            dateRecentRun = d.getTime();
                            mostRecentInext = runList.size() - 1;
                            mostRecentYear = yearDirName;
                            mostRecentDate = dateFileName;
                        }
                        if(bestPace > pace_avr) {
                            bestPace = pace_avr;
                            bestMileage = runData.mileage;
                            bestYear = yearDirName;
                            bestDate = dateFileName;
                            bestInext = runList.size() - 1;
                        }
                        if(worstPace < pace_avr) {
                            worstPace = pace_avr;
                            worstMileage = runData.mileage;
                            worstYear = yearDirName;
                            worstDate = dateFileName;
                            worstInext = runList.size() - 1;
                        }
                        allPace = Utils.countPace(allRunsTime, allMileage);
                    }
                }
            }
        }

        // 更新 UI
        if(mAllRunDataMap.size() == 0) return;
        tv_date_most_recent.setText(mostRecentYear + "-" + mostRecentDate);
        updateMode3Waveform();
        waveform_2.updateUIMode_1_Waveform(mAllRunData);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy MM-dd");
        String dateStr = sdf.format(new Date());
        String[] dateArr = dateStr.split(" ");
        HashMap<String, ArrayList<RunData>> mdRunDataMap = mAllRunDataMap.get(dateArr[0]);
        if(mdRunDataMap != null) {
            ArrayList<RunData> rdList = mdRunDataMap.get(dateArr[1]);
            if(rdList != null) {
                todayMileage = 0;
                todayRunsTime = 0;
                for(RunData rd : rdList) {
                    todayMileage += rd.mileage;
                    todayRunsTime += rd.time;
                }
                todayPace = Utils.countPace(todayRunsTime, todayMileage);
                todayCalorieExpenditure = Utils.countCalorie(sysSetWeightNow, todayMileage);
            } else {
                todayMileage = 0;
                todayPace = 0;
                todayRunsTime = 0;
                todayCalorieExpenditure = 0;
            }
        } else {
            todayMileage = 0;
            todayPace = 0;
            todayRunsTime = 0;
            todayCalorieExpenditure = 0;
        }
        tv_calorie_expenditure.setText(String.format("%.2f", todayCalorieExpenditure));

        tv_mileage_today.setText(String.format("%.2f km", todayMileage / 1000.0));
        tv_mileage_best.setText(String.format("%.2f km", bestMileage / 1000.0));
        tv_mileage_worst.setText(String.format("%.2f km", worstMileage / 1000.0));
        tv_mileage_all.setText(String.format("%.2f km", allMileage / 1000.0));

        tv_pace_today.setText(Utils.paceToString(todayPace));
        tv_pace_best.setText(Utils.paceToString(bestPace));
        tv_pace_worst.setText(Utils.paceToString(worstPace));
        tv_pace_all.setText(Utils.paceToString(allPace));
    }

    private void updateMode3Waveform() {
        if(mAllRunDataMap.size() == 0) return;
        RunData worstRunData = mAllRunDataMap.get(worstYear).get(worstDate).get(worstInext);
        RunData bestRunData = mAllRunDataMap.get(bestYear).get(bestDate).get(bestInext);
        RunData mostRecentRunData = mAllRunDataMap.get(mostRecentYear).get(mostRecentDate).get(mostRecentInext);
        waveform_1.updateUIMode_3_Waveform(worstRunData, bestRunData, mostRecentRunData, waveform3Flag);
    }

    // 应用设置
    private int sysSetLapLength = 0; // 圈长
    private boolean sysSetIsRoundMode = true; // 是否是回来模式
    private boolean sysSetLapPlanIsCheck = false; // 是否勾选计划圈数
    private int sysSetLapPlanNum = 0; // 计划圈数
    private int sysSetWeightNow = 0; // 当前体重
    // 读取应用设置
    // 设置文件的内容格式：设置项=值，每一行保存一项
    private void readAppSet() {
        ArrayList<String> lines = Utils.readFile(MainActivity.this, FILE_ROOT_DIR, FILE_SYSTEM_SET);
        if(lines == null) {
            saveAppSet();
            return;
        }
        for(String line : lines) {
            String[] arr = line.split("=");
            switch (arr[0]) {
                case "lapLength":
                    sysSetLapLength = Integer.parseInt(arr[1]);
                    break;
                case "isRoundMode":
                    sysSetIsRoundMode = Boolean.parseBoolean(arr[1]);
                    break;
                case "lapPlanIsCheck":
                    sysSetLapPlanIsCheck = Boolean.parseBoolean(arr[1]);
                    break;
                case "lapPlanNum":
                    sysSetLapPlanNum = Integer.parseInt(arr[1]);
                    break;
                case "weightNow":
                    sysSetWeightNow = Integer.parseInt(arr[1]);
                    break;
            }
        }
    }
    // 保存应用设置
    // 设置文件的内容格式：设置项=值，每一行保存一项
    private void saveAppSet() {
        StringBuilder setSb = new StringBuilder();
        setSb.append("lapLength=").append(sysSetLapLength).append("\n")
                .append("isRoundMode=").append(sysSetIsRoundMode).append("\n")
                .append("lapPlanIsCheck=").append(sysSetLapPlanIsCheck).append("\n")
                .append("lapPlanNum=").append(sysSetLapPlanNum).append("\n")
                .append("weightNow=").append(sysSetWeightNow).append("\n");
        if(!Utils.writeFile(MainActivity.this, FILE_ROOT_DIR, FILE_SYSTEM_SET, setSb.toString(), false)) {
            Utils.dplAlert(this, "无法保存设置");
        }
    }

    private int dpToPx(int dp) {
        float density = getResources().getDisplayMetrics().density;
        return Math.round(dp * density);
    }

    // 按钮的点击时间
    private long mClickTime;
    // 判断是否为快速点击
    private boolean isFastClick() {
        long clickTime = System.currentTimeMillis();
        if(clickTime - mClickTime > 200) { // 点击间隔超 200ms 则认为不是快速点击
            mClickTime = clickTime;
            return false;
        }
        return true;
    }

}